﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using EzDesk.Apps.Model.Attendance;
using EzDesk.Apps.ServiceImpl.Attendance.Evaluation;
using EzDesk.Utility.Extensions;
using EzDesk.Utility.Json;
using EzDesk.Utility.Log;
using EzDesk.Utility.ServiceStatusInfo;
using EzDesk.Apps.Data.Attendance;

namespace EzDesk.Apps.ServiceImpl.Attendance
{
    public partial class AttendanceService
    {
        #region [ private methods]
        
        #region evaluation changes
        private void addEvaluationChangeItem(Guid historyId, string itemName, string oldValue, string newValue, EzDeskAttendanceContainer container)
        {
            var changeItem = new EvaluationChangeItem()
            {
                Id = Guid.NewGuid(),
                HistoryId = historyId,
                ItemName = itemName,
                OldValue = oldValue,
                NewValue = newValue,
            };
            container.EvaluationChangeItemSet.AddObject(changeItem);
            container.SaveChanges();
        }

        private void addEvaluationChange(
            Guid historyId,
            DayAttendanceEvaluation oldAttendanceEvaluation,
            DayAttendanceEvaluation newAttendanceEvaluation,
            EzDeskAttendanceContainer container
            )
        {
            // 记录迟到时间
            if (oldAttendanceEvaluation.LateMiniutes != newAttendanceEvaluation.LateMiniutes)
            {
                addEvaluationChangeItem(
                    historyId,
                    "LateMiniutes",
                    oldAttendanceEvaluation.LateMiniutes.ToString(),
                    newAttendanceEvaluation.LateMiniutes.ToString(),
                    container
                    );
            }
            // 记录早退时间
            if (oldAttendanceEvaluation.EarlyMiniutes != newAttendanceEvaluation.EarlyMiniutes)
            {
                addEvaluationChangeItem(
                    historyId,
                    "EarlyMiniutes",
                    oldAttendanceEvaluation.EarlyMiniutes.ToString(),
                    newAttendanceEvaluation.EarlyMiniutes.ToString(),
                    container
                    );
            }
            // 记录是否缺勤
            if (oldAttendanceEvaluation.IsAbsense != newAttendanceEvaluation.IsAbsense)
            {
                addEvaluationChangeItem(
                    historyId,
                    "IsAbsense",
                    oldAttendanceEvaluation.IsAbsense.ToString(),
                    newAttendanceEvaluation.IsAbsense.ToString(),
                    container
                    );
            }
            // 记是否加班
            if (oldAttendanceEvaluation.IsExtraWork != newAttendanceEvaluation.IsExtraWork)
            {
                addEvaluationChangeItem(
                    historyId,
                    "IsExtraWork",
                    oldAttendanceEvaluation.IsExtraWork.ToString(),
                    newAttendanceEvaluation.IsExtraWork.ToString(),
                    container
                    );
            }
            // 记录实际工时
            if (oldAttendanceEvaluation.Manhours != newAttendanceEvaluation.Manhours)
            {
                addEvaluationChangeItem(
                    historyId,
                    "ManHours",
                    oldAttendanceEvaluation.Manhours.ToString(),
                    newAttendanceEvaluation.Manhours.ToString(),
                    container
                    );
            }
        }
        #endregion

        #region modify histories
        public void addModifyHistory(
             DayAttendanceEvaluation oldAttendanceEvaluation,
             DayAttendanceEvaluation newAttendanceEvaluation,
             Guid operationId,
             DateTime modifyOn,
             EzDeskAttendanceContainer container)
        {
            var userId = newAttendanceEvaluation.UserId;
            var newHistoryId = Guid.NewGuid();
            var modifyHistory = new EvaluationModifyHistory()
            {
                Id = newHistoryId,
                UserId = userId,
                Date = newAttendanceEvaluation.Date,
                ModifyOn = modifyOn,
                OperatorId = operationId,
            };
            container.EvaluationModifyHistorySet.AddObject(modifyHistory);
            container.SaveChanges();

            addEvaluationChange(newHistoryId, oldAttendanceEvaluation, newAttendanceEvaluation, container);
        }

        /// <summary>
        /// 为考勤添加一个考勤申请拒绝历史
        /// </summary>
        /// <param name="theApplication"></param>
        /// <param name="actorId"></param>
        private void addAttendanceEvaluationRejectionToHistroy(EvaluationModifyApplication theApplication, Guid actorId, EzDeskAttendanceContainer container)
        {
            // 这里的逻辑是：添加一个修改历史，但是不添加任何ChangeItem，就认为是被拒绝了
            container.EvaluationModifyHistorySet.AddObject(
                new EvaluationModifyHistory()
                {
                    Id = Guid.NewGuid(),
                    UserId = theApplication.ApplyUserId,
                    Date = theApplication.Date,
                    OperatorId = actorId,
                    ModifyOn = DateTime.Now
                });

            container.SaveChanges();

        }

        public List<EvaluationModifyHistory> getModifyHistoryByUserAndDate(DateTime date, string memberstring, EzDeskAttendanceContainer container)
        {
            var userIds = _ezApiClient.GetAllUsersByMemberString(memberstring).Select(p => p.Id).ToList();

            List<EvaluationModifyHistory> result = null;
            var query = container.EvaluationModifyHistorySet
                .Where(p => userIds.Contains(p.UserId) && p.Date == date)
                .OrderByDescending(p => p.ModifyOn)
                .ToList();

            foreach (var modifyHistory in query)
            {
                container.LoadProperty(modifyHistory, p => p.EvaluationChangeItem);
                modifyHistory.Operator = _ezApiClient.GetSimpleUserById(modifyHistory.OperatorId);
            }

            result = query;

            return result;
        }


        /// <summary>
        /// 取得考勤评估修改的历史
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="date"></param>
        /// <returns></returns>
        private List<EvaluationModifyHistory> getAttenanceEvaluationModifyHistory(DateTime date, string memberstring, EzDeskAttendanceContainer container)
        {
            date = date.Date;
            return convertEvaluationHistoryListModel(
                getModifyHistoryByUserAndDate(date, memberstring, container)
                );
        }

        #endregion

        #region day attendance evaluattion

        /// <summary>
        /// 重新评估考勤情况并获得评估结果
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="date"></param>
        /// <returns></returns>
        private DayAttendanceEvaluation evaluateAttendanceInfo(Guid userId, DateTime date, EzDeskAttendanceContainer container)
        {
            var config = getAttendanceConfig();
            var attendanceInfoList = GetAttendanceInfoListByUserInDay(date, userId).Result;
            var dayInfo = getDayInfo(date, userId, container);
            var dayLeaveInfo = getDayLeaveInfo(date, userId, container);

            var evaluator = new DayAttendanceEvaluatorEx(
                userId,
                dayInfo,
                config,
                attendanceInfoList,
                dayLeaveInfo
                );
            return evaluator.GetAttendanceEvaluation();

        }

        private DayAttendanceEvaluation refreshDayAttendanceEvaluation(Guid userId, DateTime date, EzDeskAttendanceContainer container)
        {
            date = date.Date;

            // 直接生成一个新的对象
            var evaluation = evaluateAttendanceInfo(userId, date, container);

            evaluation.Id = Guid.NewGuid();
            evaluation.UpdateOn = DateTime.Now;

            container.DayAttendanceEvaluationSet.AddObject(evaluation);
            container.SaveChanges();
            return evaluation;
        }

        /// <summary>
        /// 更新自定义考勤评估状况
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="newAttendanceEvaluation"></param>
        private void updateDayAttendanceEvaluation(DayAttendanceEvaluation newAttendanceEvaluation, EzDeskAttendanceContainer container)
        {
            container.DayAttendanceEvaluationSet.Attach(newAttendanceEvaluation);
            container.ObjectStateManager.ChangeObjectState(newAttendanceEvaluation,
                                                            EntityState.Modified);
            container.SaveChanges();
        }


        private List<DayAttendanceEvaluation> getDayAttendanceEvaluation(DateTime date, Guid userId, EzDeskAttendanceContainer container)
        {
            return getDayAttendanceEvaluations(date, date, userId, container);
        }

        private List<DayAttendanceEvaluation> getDayAttendanceEvaluations(DateTime startDate, DateTime endDate, Guid userId, EzDeskAttendanceContainer container)
        {
            var startDay = startDate.Date;
            var endDay = endDate.Date;
            var attendanceInfoList = getAttendanceInfoList(startDate, endDate, convertIdToList(userId), null, container);
            var dayLeaveInfoList = getDayLeaveInfos(startDate, endDate, userId, container);
            var evaluations = container.DayAttendanceEvaluationSet
                .Where(p => p.UserId == userId && p.Date >= startDay && p.Date <= endDay)
                .OrderBy(p => p.UpdateOn)
                .ToList();
            // var modifyApplications = getEvaluationModifyApplications(startDate, endDate, userId, container);

            var evaluationList = new List<DayAttendanceEvaluation>();
            for (var theDay = startDay; theDay <= endDay; theDay = theDay.AddDays(1))
            {
                var day = theDay;

                var evaluation = evaluations.LastOrDefault(p => p.Date == day);

                if (evaluation == null)
                {
                    evaluation = refreshDayAttendanceEvaluation(userId, day, container);
                }
                else
                {
                    evaluation.DayAttendanceInfoList = attendanceInfoList.Where(p => p.Date == day).ToList();
                    evaluation.LeaveInfo = dayLeaveInfoList.FirstOrDefault(p => p.Date == day);
                }

                evaluationList.Add(evaluation);
            }

            return evaluationList;
        }

        #endregion

        #region latest evaluation modifyHistorys
        private List<EvaluationModifyHistory> getDayLatestEvaluationModifyHistorys(DateTime startDate, DateTime endDate, string memberstring, EzDeskAttendanceContainer container)
        {
            var userIds = _ezApiClient.GetAllUsersByMemberString(memberstring).Select(p => p.Id).ToList();

            var result = new List<EvaluationModifyHistory>();

            var startDay = startDate.Date;
            var endDay = endDate.Date;
            var modifyHistories = convertEvaluationHistoryListModel(
                container.EvaluationModifyHistorySet
                    .Where(p => userIds.Contains(p.UserId) && p.Date >= startDay && p.Date <= endDay)
                    .ToList()
                );

            for (var theDay = startDay; theDay <= endDay; theDay = theDay.AddDays(1))
            {
                var day = theDay;
                var modifyHistory =
                    modifyHistories.Where(p => p.Date == day).OrderByDescending(p => p.ModifyOn).FirstOrDefault();
                if (modifyHistory != null)
                {
                    result.Add(modifyHistory);
                }
            }
            return result;
        }

        private List<EvaluationModifyHistory> getDayLatestEvaluationModifyHistory(DateTime date, string memberstring, EzDeskAttendanceContainer container)
        {
            return getDayLatestEvaluationModifyHistorys(date, date, memberstring, container);
        }
        #endregion


        #region evaluation application
        /// <summary>
        /// 添加一个新的修改考勤情况评估申请
        /// </summary>
        /// <param name="modifyApplicaiton"></param>
        private void addNewModifyAttendanceEvaluationApplication(EvaluationModifyApplication modifyApplicaiton, EzDeskAttendanceContainer container)
        {
            modifyApplicaiton.Id = Guid.NewGuid();
            container.EvaluationModifyApplicationSet.AddObject(modifyApplicaiton);
            container.SaveChanges();
        }

        /// <summary>
        /// 更新考勤评估状况修改申请状态
        /// </summary>
        /// <param name="attendanceEvaluationApplication"></param>
        private void updateEvaluationModifyApplication(EvaluationModifyApplication attendanceEvaluationApplication, EzDeskAttendanceContainer container)
        {
            container.EvaluationModifyApplicationSet.Attach(attendanceEvaluationApplication);
            container.ObjectStateManager.ChangeObjectState(attendanceEvaluationApplication,
                                                            EntityState.Modified);
            container.SaveChanges();
        }



        /// <summary>
        /// 直接获得当前正在进行中的考勤状况修改评估申请
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="date"></param>
        /// <returns></returns>
        private List<EvaluationModifyApplication> getCurrentAttendanceEvaluationModifyApplication(DateTime date, string memberstring, EzDeskAttendanceContainer container)
        {
            return getCurrentAttendanceEvaluationModifyApplications(date, date, memberstring, container);
        }

        /// <summary>
        /// 直接获得当前正在进行中的考勤状况修改评估申请
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="date"></param>
        /// <returns></returns>
        private List<EvaluationModifyApplication> getCurrentAttendanceEvaluationModifyApplications(DateTime startDate, DateTime endDate, string memberstring, EzDeskAttendanceContainer container)
        {
            // todo: 
            var userIds = _ezApiClient.GetAllUsersByMemberString(memberstring).Select(p=>p.Id).ToList();

            var startDay = startDate.Date;
            var endDay = endDate.Date;

            var result = new List<EvaluationModifyApplication>();

            var applicationLists =
                container.EvaluationModifyApplicationSet.Where(
                    p => userIds.Contains(p.ApplyUserId) && p.Date >= startDay & p.Date <= endDay)
                    .ToList();

            // 按时间顺序找每天的最新的一个
            for (var theDay = startDay; theDay <= endDay; theDay = theDay.AddDays(1))
            {
                var day = theDay;

                var application = applicationLists
                    .Where(p => p.Date == day)
                    .OrderByDescending(p => p.ApplyOn)
                    .FirstOrDefault(p => p.StateValue == (int)ApplyState.Applying);

                if (application == null) continue;

                application = convertEvaluationModifyApplicationModel(application);
                result.Add(application);
            }

            return result;
        }


        /// <summary>
        /// 获得某人所有的考勤评估申请
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="date"></param>
        /// <returns></returns>
        private List<EvaluationModifyApplication> getEvaluationModifyApplications(DateTime startDate, DateTime endDate, Guid userId, EzDeskAttendanceContainer container)
        {
            var startDay = startDate.Date;
            var endDay = endDate.Date;

            return
                container.EvaluationModifyApplicationSet.Where(
                    p => p.ApplyUserId == userId && p.Date >= startDay && p.Date <= endDay)
                    .Select(convertEvaluationModifyApplicationModel)
                    .ToList();
        }

        /// <summary>
        /// 获得某人所有的考勤评估申请
        /// </summary>
        /// <param name="date"></param>
        /// <param name="memberstring"></param>
        /// <returns></returns>
        private List<EvaluationModifyApplication> getEvaluationModifyApplication(DateTime date, Guid userId, EzDeskAttendanceContainer container)
        {
            return getEvaluationModifyApplications(date, date, userId, container);
        }

        #endregion 



        











        #region feeds methods
        /// <summary>
        /// 申请修改考勤评估后，发送Feed
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="date"></param>
        /// <param name="applyText"></param>
        private void sendApplyEvaluationModifyFeed(EvaluationModifyApplication modifyApplication, string applyText)
        {
            var userId = modifyApplication.ApplyUserId;
            var date = modifyApplication.Date;
            var senderUser = _ezApiClient.GetSimpleUserById(userId);

            string dateStr = date.ToFullDate();
            string dateEpoch = date.ToEpoch().ToString();

            var feedData = new Dictionary<string, string>
                               {
                                   {"sender", senderUser.Name},
                                   {"dateStr", dateStr},
                                   {"dateEpoch", dateEpoch},
                                   {"targetUserId", userId.ToString()},
                                   {"applyText", applyText},
                               };

            // 发送目标为所有hr
            var memberString = _ezApiClient.GetGroupByName("attendance_hr").Memberstring;

            var feedId = _ezApiClient.SendFeed(
                FeedTemplateStr_attendance_applyEvaluationModify,
                JsonHelper.ConvertToJson(feedData),
                memberString
                );
            _ezApiClient.SetFeedRecord(modifyApplication.Id, FeedTemplateStr_attendance_applyEvaluationModify,
                                       userId.ToString(), feedId, null);
        }

        /// <summary>
        /// 发送考勤评估信息已经修改的Feed
        /// </summary>
        /// <param name="operatorId"></param>
        /// <param name="newAttendanceEvaluation"></param>
        private void sendEvalationModifiedFeed(Guid operatorId, DayAttendanceEvaluation oldAttendanceEvaluation, DayAttendanceEvaluation newAttendanceEvaluation)
        {
            var operatorUser = _ezApiClient.GetSimpleUserById(operatorId);
            DateTime today = newAttendanceEvaluation.Date;
            string dateStr = today.ToFullDate();
            string dateEpoch = today.ToEpoch().ToString();

            var isFirst = true;
            var modifyHistroyBuild = new StringBuilder();
            if (newAttendanceEvaluation.IsAbsense != oldAttendanceEvaluation.IsAbsense)
            {
                var isAbsenseOld = "是";
                var isAbsenseNew = "是";
                if (oldAttendanceEvaluation.IsAbsense == false)
                {
                    isAbsenseOld = "否";
                }

                if (newAttendanceEvaluation.IsAbsense == false)
                {
                    isAbsenseNew = "否";
                }
                modifyHistroyBuild.AppendFormat("将旷工 {0} 改为 {1}", isAbsenseOld, isAbsenseNew);
                isFirst = false;
            }
            if (newAttendanceEvaluation.IsExtraWork != oldAttendanceEvaluation.IsExtraWork)
            {
                var isExtraWorkNew = "是";
                var isExtraWorkOld = "是";
                if (oldAttendanceEvaluation.IsExtraWork == false)
                {
                    isExtraWorkOld = "否";
                }
                if (newAttendanceEvaluation.IsExtraWork == false)
                {
                    isExtraWorkNew = "否";
                }
                if (!isFirst)
                {
                    modifyHistroyBuild.Append("<br />");
                }
                modifyHistroyBuild.AppendFormat("将加班 {0}改为 {1}", isExtraWorkOld, isExtraWorkNew);
                isFirst = false;
            }
            if (newAttendanceEvaluation.LateMiniutes != oldAttendanceEvaluation.LateMiniutes)
            {
                if (!isFirst)
                {
                    modifyHistroyBuild.Append("<br />");
                }
                modifyHistroyBuild.AppendFormat("将迟到 {0} 分钟 改为 {1} 分钟", oldAttendanceEvaluation.LateMiniutes, newAttendanceEvaluation.LateMiniutes);
                isFirst = false;
            }
            if (newAttendanceEvaluation.EarlyMiniutes != oldAttendanceEvaluation.EarlyMiniutes)
            {
                if (!isFirst)
                {
                    modifyHistroyBuild.Append("<br />");
                }
                modifyHistroyBuild.AppendFormat("将早退 {0} 分钟 改为 {1} 分钟", oldAttendanceEvaluation.EarlyMiniutes, newAttendanceEvaluation.EarlyMiniutes);
                isFirst = false;
            }
            if (newAttendanceEvaluation.Manhours != oldAttendanceEvaluation.Manhours)
            {
                if (!isFirst)
                {
                    modifyHistroyBuild.Append("<br />");
                }
                modifyHistroyBuild.AppendFormat("将获得工时 {0} 小时 改为 {1} 小时", oldAttendanceEvaluation.Manhours.DivEx(10), newAttendanceEvaluation.Manhours.DivEx(10));
                isFirst = false;
            }

            var feedData = new Dictionary<string, string>
                               {
                                   {"actor", operatorUser.Name},
                                   {"dateStr", dateStr},
                                   {"dateEpoch", dateEpoch},
                                   {"modifyHistory", modifyHistroyBuild.ToString()}
                               };

            // 发送给被修改考勤评估的人
            string memberString = newAttendanceEvaluation.UserId.ToString();

            _ezApiClient.SendFeed(
                FeedTemplateStr_attendance_evaluationModified,
                JsonHelper.ConvertToJson(feedData),
                memberString
                );

        }


        /// <summary>
        /// 发送申请被拒绝的Feed
        /// </summary>
        private void sendEvalationRejectedFeed(Guid actorId, EvaluationModifyApplication theApplication)
        {
            var actor = _ezApiClient.GetSimpleUserById(actorId);
            var feedData = new Dictionary<string, string>
                               {
                                   {"actor", actor.Name},
                                   {"dateStr", theApplication.Date.ToFullDate()},
                                   {"timeEpoch", theApplication.Date.ToEpoch().ToString()},
                               };
            _ezApiClient.SendFeed(
                FeedTemplateStr_attendance_evaluationRejected,
                JsonHelper.ConvertToJson(feedData),
                theApplication.ApplyUserId.ToString()
                );
        }

        /// <summary>
        /// 根据申请人，申请时间，获得申请修改考勤评估的Feed
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="date"></param>
        private void removeEvalationModifiedFeed(Guid feedId)
        {
            if (feedId != Guid.Empty)
            {
                // 获取，让所有HR的收到的提醒都失效
                var memberString = _ezApiClient.GetGroupByName("attendance_hr").Memberstring;
                _ezApiClient.SetFeedIsAvailable(feedId, memberString, false);
            }
        }
        #endregion

        #region [ conver-to Methods ]
        /// <summary>
        /// 转换完整的EvaluationModifyApplication实体
        /// </summary>
        /// <param name="applicaiton"></param>
        private EvaluationModifyApplication convertEvaluationModifyApplicationModel(EvaluationModifyApplication applicaiton)
        {
            if (applicaiton != null)
            {
                if (applicaiton.ApplyUserId != Guid.Empty)
                {
                    applicaiton.ApplyUser = _ezApiClient.GetSimpleUserById(applicaiton.ApplyUserId);
                }
            }
            return applicaiton;
        }

        /// <summary>
        /// 转换完整的convertEvaluationHistoryList实体
        /// </summary>
        /// <param name="evaluationModifyHistory"></param>
        private List<EvaluationModifyHistory> convertEvaluationHistoryListModel(List<EvaluationModifyHistory> evaluationModifyHistory)
        {
            if (evaluationModifyHistory != null)
            {
                foreach (EvaluationModifyHistory modifyHistory in evaluationModifyHistory)
                {
                    if (modifyHistory.OperatorId != Guid.Empty)
                    {
                        modifyHistory.Operator = _ezApiClient.GetSimpleUserById(modifyHistory.OperatorId);
                    }
                }
            }

            return evaluationModifyHistory;
        }
        #endregion


        #endregion
        
        #region [ public methods ]
        public StatusInfo<List<DayAttendanceEvaluation>> GetDayAttendanceEvaluation(Guid userId, DateTime date)
        {
            return StatusInfo.Wrap(
                () => EzDeskAttendanceContainer.Go(
                    container => getDayAttendanceEvaluation(date, userId, container))
                );
        }

        public StatusInfo<List<DayAttendanceEvaluation>> GetDayAttendanceEvaluations(Guid userId, DateTime startDate, DateTime endDate)
        {
            LogEx.TRACE("AttendanceService - GetDayAttendanceEvaluations", "请求拿一个用户一个月的DayAttendanceEvaluations");
            var result = StatusInfo.Wrap(
                () => EzDeskAttendanceContainer.Go(
                    container => getDayAttendanceEvaluations(startDate, endDate, userId, container))
                );
                
            LogEx.TRACE("AttendanceService - GetDayAttendanceEvaluations", "拿一个用户一个月的DayAttendanceEvaluations结束");
            return result;
        }


        public StatusInfo ApplyEvaluationModify(Guid userId, DateTime date, string applyText)
        {
            return StatusInfo.Wrap(
                () => EzDeskAttendanceContainer.Go(
                    container =>
                        {
                            date = date.Date;

                            if (DateTime.Now.Date <= date)
                            {
                                LogEx.EXCEPT("Attendance - ApplyEvaluationModify", "还没到这一天，没法处理这一天的考勤评估修改");
                                throw new Exception("还没到这一天，没法处理这一天的考勤评估修改");
                            }

                            // 如果已经有提交的正在处理中的申请，那么不允许多次提交
                            if (getCurrentAttendanceEvaluationModifyApplication(date, userId.ToString(), container).Count > 0)
                            {
                                LogEx.EXCEPT("Attendance - ApplyEvaluationModify", "重复提交修改考勤评估申请");
                                throw new Exception("重复提交修改考勤评估申请");
                            }

                            var modifyApplicaiton = new EvaluationModifyApplication()
                                                        {
                                                            ApplyOn = DateTime.Now,
                                                            ApplyUserId = userId,
                                                            ApplyText = applyText,
                                                            Date = date.Date,
                                                            State = ApplyState.Applying,
                                                        };

                            addNewModifyAttendanceEvaluationApplication(modifyApplicaiton, container);

                            sendApplyEvaluationModifyFeed(modifyApplicaiton, applyText);
                        })
                );
        }

        public StatusInfo<List<EvaluationModifyApplication>> GetCurrentEvaluationModifyApplication(string memberstring, DateTime date)
        {
            return StatusInfo.Wrap(
                () => EzDeskAttendanceContainer.Go(
                    container =>
                    getCurrentAttendanceEvaluationModifyApplication(date, memberstring, container))
                );
        }
        public StatusInfo<List<EvaluationModifyApplication>> GetCurrentEvaluationModifyApplications(string memberstring, DateTime startDate, DateTime endDate)
        {
            LogEx.TRACE("AttendanceService - CurrentEvaluationModifyApplications", "请求拿一个用户一个月的CurrentEvaluationModifyApplications");
            var result =
                StatusInfo.Wrap(
                    () =>
                    EzDeskAttendanceContainer.Go(
                        container => getCurrentAttendanceEvaluationModifyApplications(startDate, endDate, memberstring, container)
                        )
                    );

            LogEx.TRACE("AttendanceService - CurrentEvaluationModifyApplications", "拿一个用户一个月的CurrentEvaluationModifyApplications结束");
            return result;
        }

        public StatusInfo<List<EvaluationModifyHistory>> GetDayLatestEvaluationModifyHistorys(string memberstring, DateTime startDate, DateTime endDate)
        {
            LogEx.TRACE("AttendanceService - CurrentEvaluationModifyApplications", "请求拿一个用户一个月的LatestEvaluationModifyHistory");
            var result =
                StatusInfo.Wrap(
                    () =>
                    EzDeskAttendanceContainer.Go(
                        container => getDayLatestEvaluationModifyHistorys(startDate, endDate, memberstring, container)
                        )
                    );

            LogEx.TRACE("AttendanceService - CurrentEvaluationModifyApplications", "拿一个用户一个月的LatestEvaluationModifyHistory结束");
            return result;
        }

        
        public StatusInfo<List<EvaluationModifyHistory>> GetDayLatestEvaluationModifyHistory(string memberstring, DateTime date)
        {
            return StatusInfo.Wrap(
                () => EzDeskAttendanceContainer.Go(
                    container => getDayLatestEvaluationModifyHistory(date, memberstring, container)
                          )
                );
        }

        public StatusInfo<List<EvaluationModifyApplication>> GetEvaluationModifyApplications(Guid userId, DateTime date)
        {
            return StatusInfo.Wrap(
                () => EzDeskAttendanceContainer.Go(
                    container =>
                    getEvaluationModifyApplication(date, userId, container))
                );
        }

        public StatusInfo<List<EvaluationModifyHistory>> GetEvaluationModifyHistory(Guid userId, DateTime date)
        {
            return StatusInfo.Wrap(
                () => EzDeskAttendanceContainer.Go(
                    container =>
                    getAttenanceEvaluationModifyHistory(date,userId.ToString(), container)
                          )
                );
        }

        public StatusInfo ModifyEvaluation(DayAttendanceEvaluation newAttendanceEvaluation, Guid operatorId)
        {
            return StatusInfo.Wrap(
                () => EzDeskAttendanceContainer.Go(
                    container =>
                        {

                            var userId = newAttendanceEvaluation.UserId;
                            var date = newAttendanceEvaluation.Date = newAttendanceEvaluation.Date.Date;

                            // 为考勤添加一个考勤历史
                            var oldAttendanceEvaluation = GetDayAttendanceEvaluation(userId, date).Result.FirstOrDefault();

                            addModifyHistory(oldAttendanceEvaluation, newAttendanceEvaluation, operatorId,
                                             DateTime.Now, container);

                            // 更新考勤评估记录
                            updateDayAttendanceEvaluation(newAttendanceEvaluation, container);

                            // 将当前的考勤申请变为已处理
                            var currentEvaluationApplication =
                                getCurrentAttendanceEvaluationModifyApplication(date, userId.ToString(), container).FirstOrDefault();
                            if (currentEvaluationApplication != null)
                            {
                                currentEvaluationApplication.State = ApplyState.Done;
                                updateEvaluationModifyApplication(currentEvaluationApplication, container);

                                // 删除申请修改考勤评估记录的Feed
                                var feedId = _ezApiClient.GetFeedRecord(currentEvaluationApplication.Id,
                                                                        FeedTemplateStr_attendance_applyEvaluationModify,
                                                                        userId.ToString());
                                removeEvalationModifiedFeed(Guid.Parse(feedId));
                            }
                            // 发送考勤评估记录已修改的Feed
                            sendEvalationModifiedFeed(operatorId, oldAttendanceEvaluation,
                                                      newAttendanceEvaluation);
                        })
                );
        }

        public StatusInfo RejectEvaluationApplication(Guid actorId, Guid applicationId)
        {
            return StatusInfo.Wrap(
                () => EzDeskAttendanceContainer.GoAndSave(
                    container =>
                        {
                            var theApplication =
                                container.EvaluationModifyApplicationSet.FirstOrDefault(
                                    p => p.Id == applicationId);

                            // 为考勤添加一个考勤申请拒绝历史
                            addAttendanceEvaluationRejectionToHistroy(theApplication, actorId, container);

                            if (theApplication.State == ApplyState.Applying)
                            {
                                // 确保这个申请当前有效
                                theApplication.State = ApplyState.Done;
                                updateEvaluationModifyApplication(theApplication, container);

                                // 删除申请修改考勤评估记录的Feed
                                var feedId = _ezApiClient.GetFeedRecord(theApplication.Id,
                                                                        FeedTemplateStr_attendance_applyEvaluationModify,
                                                                        theApplication.ApplyUserId.ToString());
                                removeEvalationModifiedFeed(Guid.Parse(feedId));
                            }
                            // 发送申请被拒绝的Feed


                            // todo:发送申请被拒绝的Feed
                            sendEvalationRejectedFeed(actorId, theApplication);
                        }));
        }
        #endregion

    }
}
